package com.utooo.service.exchangedata.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.utooo.enums.ApiEnum;
import com.utooo.pojo.dto.exchangedata.RequestResultDto;
import com.utooo.service.exchangedata.ExchangeDataService;
import com.utooo.service.exchangedata.HttpService;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class ExchangeDataServiceImpl implements ExchangeDataService {
    private final HttpService httpServiceImpl;
    private Map<String, String> headerMap;
    private long lastUpdatedTime; // 记录上次更新时间
    private static final long TOKEN_EXPIRY_TIME = (long) (3600 * 1000 * 1.5); // 设置有效期为1.5小时

    @Value("${exchange-data.prefix}")
    private String prefixUrl; // 从配置文件中获取URL前缀

    @Value("${exchange-data.clientId}")
    private String clientId; // 从配置文件中获取client_id

    @Value("${exchange-data.clientSecret}")
    private String clientSecret; // 从配置文件中获取client_secret

    @Value("${exchange-data.grantType}")
    private String grantType; // 从配置文件中获取grant_type

    @Override
    @PostConstruct
    public Map<String, String> getTokenHeaderMap() {
        // 如果headerMap为空或者已经过期，则重新获取
        if (headerMap == null || System.currentTimeMillis() - lastUpdatedTime > TOKEN_EXPIRY_TIME) {
            String url = prefixUrl + ApiEnum.GET_TOKEN.getUrl(); // 使用配置中的前缀拼接URL
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("grant_type", grantType); // 使用配置中的grant_type
            paramMap.put("client_id", clientId); // 使用配置中的client_id
            paramMap.put("client_secret", clientSecret); // 使用配置中的client_secret

            // 更新最后获取时间
            lastUpdatedTime = System.currentTimeMillis();
            String response = httpServiceImpl.sendGetRequest(url, paramMap, null);
            headerMap = new HashMap<>();
            // 解析JSON并提取access_token
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                Map<String, Object> responseMap = objectMapper.readValue(response, Map.class);
                if (responseMap.containsKey("code") && responseMap.get("code").equals("200")) {
                    headerMap.put("client_id", clientId); // 使用配置中的client_id
                    headerMap.put("client_token", (String) responseMap.get("client_token"));
                }
            } catch (Exception e) {
                throw new RuntimeException("Failed to parse token response", e);
            }
        }
        return headerMap;
    }

    @Override
    public RequestResultDto exchangeDate(ApiEnum apiEnum, Map<String, String> params, Map<String, String> headers) {
        RequestResultDto requestResultDto = new RequestResultDto();
        requestResultDto.setCode("500");
        if (apiEnum == null) {
            throw new IllegalArgumentException("ApiEnum cannot be null");
        }

        String url = prefixUrl + apiEnum.getUrl();
        String response;

        // 根据请求方法调用不同的接口
        if ("GET".equalsIgnoreCase(apiEnum.getMethod())) {
            response = httpServiceImpl.sendGetRequest(url, params, headers);
        } else if ("POST".equalsIgnoreCase(apiEnum.getMethod())) {
            response = httpServiceImpl.sendPostRequest(url, params, headers);
        } else {
            throw new UnsupportedOperationException("Unsupported HTTP method: " + apiEnum.getMethod());
        }

        // 对返回数据进行初步校验
        if (response == null || response.isEmpty()) {
            throw new RuntimeException("Empty response from API: " + apiEnum.getDescription());
        }
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> responseMap = objectMapper.readValue(response, Map.class);

            // 检查返回的状态码是否匹配预期
            if (!responseMap.containsKey(apiEnum.getStatusKey()) || 
                !apiEnum.getStatusValue().equals(responseMap.get(apiEnum.getStatusKey()).toString())) {
                throw new RuntimeException("API response status mismatch: " + response);
            }else{
                requestResultDto.setCode("200");
                requestResultDto.setData(response);
            }
            return requestResultDto;
        } catch (Exception e) {
            throw new RuntimeException("Failed to parse API response", e);
        }
    }
}